using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
namespace CSUtils
{
    public class CFile
    {
        const string _tag = "CFile";

        /// <summary>
        /// 删除掉空文件夹,所有没有子“文件系统”的都将被删除
        /// </summary> 
        public static void KillEmptyFolder(string sPath, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"KillEmptyFolder..{callLog}...{sPath}");
            if (Directory.Exists(sPath))
            {
                //DirectoryInfo info = new DirectoryInfo(sPath);
                var dirArr = Directory.GetDirectories(sPath, "*", SearchOption.AllDirectories);
                for (int i = 0; i < dirArr.Length; i++)
                {
                    var dir = dirArr[i];
                    if (Directory.Exists(dir))
                    {
                        string[] fileArr = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories);
                        int count = 0;
                        for (int i3 = 0; i3 < fileArr.Length; i3++)
                        {
                            if (fileArr[i3].EndsWith(".DS_Store") == false)
                            {
                                count++;
                            }
                        }
                        if (count == 0)
                        {
                            CLog.E(_tag, $"删除空目录.......{dir}");
                            Directory.Delete(dir, true);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 删除掉空文件夹
        /// 所有没有子“文件系统”的都将被删除
        /// </summary> 
        public static void KillEmptyDirectory(string storagepath, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"KillEmptyDirectory..{callLog}...{storagepath}");
            DirectoryInfo dir = new DirectoryInfo(storagepath);
            DirectoryInfo[] subdirArr = dir.GetDirectories("*.*", SearchOption.AllDirectories);
            foreach (DirectoryInfo subdir in subdirArr)
            {
                FileSystemInfo[] subFiles = subdir.GetFileSystemInfos();
                if (subFiles.Count() == 0)
                {
                    CLog.E(_tag, $"删除目录.......{subdir.FullName}");
                    subdir.Delete();
                }
            }
        }

        /// <summary>
        /// 获取相对路径
        /// </summary>
        public static string GetRelativePath(string rootPath, string targetPath)
        {
            rootPath = new DirectoryInfo(rootPath).FullName;
            targetPath = new DirectoryInfo(targetPath).FullName;
            rootPath = rootPath.Replace("\\", "/");
            targetPath = targetPath.Replace("\\", "/");
            //rootPath = rootPath.DirFormat(2);
            //targetPath = targetPath.DirFormat(2);

            int index = 0;
            for (int i = 0; i < rootPath.Length; i++)
            {
                if (targetPath.Length <= i || rootPath[i] != targetPath[i])
                {
                    index = i - 1;
                    break;
                } else if (i == rootPath.Length - 1)
                {
                    index = rootPath.Length;
                    break;
                }
            }
            if (index == rootPath.Length)
            {
                if (targetPath.Length == rootPath.Length)
                {
                    targetPath = "";
                } else
                {
                    targetPath = targetPath.Substring(index + 1);
                }
                rootPath = "";
            } else if (index >= 0)
            {
                targetPath = targetPath.Substring(index + 1);
                rootPath = rootPath.Substring(index + 1);
            }
            string path = "";
            if (string.IsNullOrEmpty(rootPath) == false)
            {
                path = "../";
                for (int i = 0; i < rootPath.Length; i++)
                {
                    if (rootPath[i] == '/')
                    {
                        path += "../";
                    }
                }
            }
            path += targetPath;
            return path;
        }

        public static void CopyDir(string sourceDir, string targetDir, bool isDelectTargetDir = true, string callLog = "", string[] ignoreSuffixArr = null, string encryptKey = null, string decryptKey = null)
        {
            CopyDirectory(sourceDir, targetDir, "*", SearchOption.AllDirectories, isDelectTargetDir, callLog, ignoreSuffixArr, encryptKey, decryptKey);
        }

        public static void CopyDirectory(string sourceDir, string targetDir, string searchPattern, SearchOption searchOption, bool isDelectTargetDir = true, string callLog = "", string[] ignoreSuffixArr = null, string encryptKey = null, string decryptKey = null)
        {
            sourceDir = new DirectoryInfo(sourceDir).FullName;
            if (Directory.Exists(sourceDir) == false)
            {
                CLog.E(_tag, $"无法拷贝.....目录不存在......{sourceDir}\n.........{targetDir}");
                return;
            }
            targetDir = new DirectoryInfo(targetDir).FullName;
            if (sourceDir == targetDir)
            {
                CLog.E(_tag, $"不用拷贝.....目录相同......{sourceDir}\n.........{targetDir}");
                return;
            }
            if (callLog != null)
                CLog.i(_tag, $"CopyDirectory..{callLog}......{sourceDir}.........{targetDir}....isDelectTargetDir={isDelectTargetDir}");
            if (isDelectTargetDir && Directory.Exists(targetDir))
            {
                CLog.i(_tag, $"Directory.Delete..{callLog}......{sourceDir}.........{targetDir}....isDelectTargetDir={isDelectTargetDir}");
                Directory.Delete(targetDir, true);
            }
            var filePathArr = Directory.GetFiles(sourceDir, searchPattern, searchOption);
            for (int i = 0; i < filePathArr.Length; i++)
            {
                var filePath = filePathArr[i];
                if (filePath.IsMatching(ignoreSuffixArr, EMatchingType.EndsWith))
                {
                    continue;
                }
                var fileName = filePath.Substring(sourceDir.Length);
                var targetPath = targetDir + fileName;
                CopyFile(filePath, targetPath, callLog + fileName, encryptKey, decryptKey);
            }
        }

        public static void Copy(string sourcePath, string targetPath, string callLog = "", string encryptKey = null, string decryptKey = null)
        {
            CopyFile(sourcePath, targetPath, callLog, encryptKey, decryptKey);
        }

        public static void CopyFile(string sourcePath, string targetPath, string callLog = "", string encryptKey = null, string decryptKey = null)
        {
            if (File.Exists(sourcePath) == false)
            {
                CLog.E(_tag, $"无法拷贝.....文件不存在......{sourcePath}\n.........{targetPath}");
                return;
            }
            if (File.Exists(targetPath))
            {
                if (callLog != null)
                    CLog.E(_tag, $"CopyFile...删除老文件..Delete.....{targetPath}");
                File.Delete(targetPath);
            }
            if (callLog != null)
                CLog.i(_tag, $"CopyFile..{callLog}.........{sourcePath}.........{targetPath}.....encryptKey={encryptKey}/decryptKey={decryptKey}");

            string dir = Path.GetDirectoryName(targetPath);
            if (Directory.Exists(dir) == false)
            {
                Directory.CreateDirectory(dir);
            }
            //CLog.i(tag, $"拷贝完成.........{sourcePath}.........{targetPath}");
            if (encryptKey == null && decryptKey == null)
            {
                File.Copy(sourcePath, targetPath);
            } else if (encryptKey != null)
            {
                var bytes = File.ReadAllBytes(sourcePath);
                //bytes = CAES.AESEncrypt(bytes, encryptKey, callLog);
                File.WriteAllBytes(targetPath, bytes);
            } else if (decryptKey != null)
            {
                var bytes = File.ReadAllBytes(sourcePath);
                //bytes = CAES.AESDecrypt(bytes, decryptKey, callLog);
                File.WriteAllBytes(targetPath, bytes);
            }
        }

        public static void Move(string sourcePath, string targetPath, string callLog = "")
        {
            MoveFile(sourcePath, targetPath, callLog);
        }

        public static void MoveFile(string sourcePath, string targetPath, string callLog = "")
        {
            if (sourcePath == targetPath)
            {
                return;
            }
            if (callLog != null)
                CLog.i(_tag, $"Move..{callLog}...........{sourcePath}.........{targetPath}");
            if (File.Exists(sourcePath) == false)
            {
                CLog.E(_tag, $"无法移动.....文件不存在......{targetPath}");
                return;
            }
            if (File.Exists(targetPath))
            {
                CLog.E(_tag, $"MoveFile...Delete.....{targetPath}");
                File.Delete(targetPath);
            }
            string dir = Path.GetDirectoryName(targetPath);
            if (Directory.Exists(dir) == false)
            {
                Directory.CreateDirectory(dir);
            }
            if (targetPath.EndsWith(".zip", StringComparison.Ordinal))
            {
                File.Copy(sourcePath, targetPath);
                File.Delete(sourcePath);
            } else
            {
                File.Move(sourcePath, targetPath);
            }
            //CLog.i(tag, $"移动文件完成...........{targetPath}"); 
        }

        public static void MoveDir(string sourceDir, string targetDir, string callLog = "")
        {
            if (sourceDir == targetDir)
            {
                return;
            }
            if (callLog != null)
                CLog.i(_tag, $"MoveDir..{callLog}...........{sourceDir}.........{targetDir}");
            if (Directory.Exists(sourceDir) == false)
            {
                CLog.E(_tag, $"无法移动目录.....文件不存在......{targetDir}");
                return;
            }
            if (Directory.Exists(targetDir))
            {
                CLog.E(_tag, $"MoveDir...Delete.....{targetDir}");
                Directory.Delete(targetDir, true);
            }
            string dir = Path.GetDirectoryName(targetDir);
            if (Directory.Exists(dir) == false)
            {
                Directory.CreateDirectory(dir);
            }
            Directory.Move(sourceDir, targetDir);
            //CLog.i(tag, $"移动文件完成...........{targetPath}"); 
        }

        public static void DeleteNullDir(string dir, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"DeleteNullDir..{callLog}......删除的目录....{dir}");
            string[] dirArr = Directory.GetDirectories(dir, "*", SearchOption.AllDirectories);
            dirArr = dirArr.OrderByDescending(n => n.Length).ToArray();
            for (int i = 0; i < dirArr.Length; i++)
            {
                string dir2 = dirArr[i];
                string[] fileArr = Directory.GetFiles(dir2, "*", SearchOption.AllDirectories);
                if (fileArr.Length == 0)
                {
                    CLog.E(_tag, $"删除的目录.................{dir2}");
                    Directory.Delete(dir2, true);
                }
            }
        }

        //数据存储路径--------------
        //PC端------Application.dataPath
        //移动端-----Application.persistentDataPath
        public static bool SaveFile(byte[] data, string path)
        {
            if (File.Exists(path))
                File.Delete(path); //文件存在就删除
            using (FileStream stream = new FileStream(path, FileMode.Create))
            {
                stream.Position = 0;
                stream.Write(data, 0, data.Length);
                stream.Flush();
                stream.Close();
                return true;
            }
        }

        public static string[] ReadAllLines(string fullPath, string callLog = "")
        {
            if (File.Exists(fullPath) == false)
            {
                CLog.E(_tag, $"文件不存在...读取失败......{fullPath}");
                return null;
            }
            if (callLog != null)
                CLog.i(_tag, $"ReadAllLines....{callLog}.....{fullPath}");
            var arr = File.ReadAllLines(fullPath);
            return arr;
        }

        public static string ReadAllText(string fullPath, string callLog = "")
        {
            if (File.Exists(fullPath) == false)
            {
                if (callLog != null)
                    CLog.E(_tag, $"文件不存在...读取失败......{fullPath}");
                return null;
            }
            if (callLog != null)
                CLog.i(_tag, $"ReadAllText....{callLog}.....{fullPath}");
            var arr = File.ReadAllText(fullPath);
            return arr;
        }

        public static byte[] ReadAllBytes(string fullPath, string callLog = "", string encryptKey = null)
        {
            if (File.Exists(fullPath) == false)
            {
                if (callLog != null)
                {
                    CLog.E(_tag, $"文件不存在...读取失败......{fullPath}");
                }
                return null;
            }
            if (callLog != null)
            {
                CLog.i(_tag, $"ReadAllBytes....{callLog}.....{fullPath}");
            }
            var bytes = File.ReadAllBytes(fullPath);
            if (string.IsNullOrEmpty(encryptKey) == false)
            {
                // bytes = CAES.AESDecrypt(bytes, encryptKey, callLog);
            }
            return bytes;
        }

        public static byte[] ReadFile(string path, string callLog = "", string encryptKey = null)
        {
            return ReadAllBytes(path, callLog, encryptKey);
        }

        public static void WriteAllText(string fullPath, string data, string callLog = "")
        {
            WriteAllText(fullPath, data, null, callLog);
        }

        public static void WriteAllText(string fullPath, string data, Encoding encoding, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"WriteAllText()....{callLog}.....{fullPath}...\n\n{data}\n\n");
            string dir = Path.GetDirectoryName(fullPath);
            if (Directory.Exists(dir) == false)
            {
                Directory.CreateDirectory(dir);
            }
            if (File.Exists(fullPath))
            {
                if (callLog != null)
                    CLog.i(_tag, $"WriteAllText().Delete().....{fullPath}");
                File.Delete(fullPath);
            }
            if (encoding == null)
            {
                File.WriteAllText(fullPath, data);
            } else
            {
                File.WriteAllText(fullPath, data, encoding);
            }
        }

        /// <summary>
        /// path=="C:\测试_临时文件\nn22\ddd.xml"
        /// </summary>
        public static void TxtWriter(List<string> contentList, string path)
        {
            if (File.Exists(path))
                File.Delete(path); //文件存在就删除
            StreamWriter sw;
            FileStream fs;
            if (!File.Exists(path))
            {
                fs = new FileStream(path, FileMode.Create, FileAccess.Write);
                fs.Close();
            }
            sw = File.AppendText(path);
            for (int i = 0; i < contentList.Count; i++)
            {
                sw.WriteLine(contentList[i]);
            }
            sw.Close();
        }

        public static void WriteAllByte(string fullPath, byte[] byteArr, string callLog = "", string encryptKey = null, string decryptKey = null)
        {
            if (byteArr == null)
            {
                CLog.E(_tag, $"WriteAllByte..错误......{callLog}.......byteArr=null.{fullPath}");
                return;
            }
            if (callLog != null)
            {
                CLog.i(_tag, $"WriteAllByte....{callLog}.....{fullPath}");
            }
            string dir = Path.GetDirectoryName(fullPath);
            if (Directory.Exists(dir) == false)
            {
                Directory.CreateDirectory(dir);
            }
            if (File.Exists(fullPath))
            {
                if (callLog != null)
                {
                    CLog.E(_tag, $"WriteAllByte...Delete.....{callLog}........{fullPath}");
                }
                File.Delete(fullPath);
            }

            if (encryptKey == null && decryptKey == null)
            {
                File.WriteAllBytes(fullPath, byteArr);
            } else if (encryptKey != null)
            {
                // byteArr = CAES.AESEncrypt(byteArr, encryptKey, callLog);
                File.WriteAllBytes(fullPath, byteArr);
            } else if (decryptKey != null)
            {
                // byteArr = CAES.AESDecrypt(byteArr, decryptKey, callLog);
                File.WriteAllBytes(fullPath, byteArr);
            }
        }

        public static void WriteAllBytes(string fullPath, params byte[][] byteArrArr)
        {
            if (byteArrArr == null)
            {
                CLog.E(_tag, $"WriteAllByte..错误.....byteArrArr=null.{fullPath}");
                return;
            }
            CLog.i(_tag, $"WriteAllBytes....{fullPath}");
            string dir = Path.GetDirectoryName(fullPath);
            if (Directory.Exists(dir) == false)
            {
                Directory.CreateDirectory(dir);
            }
            if (File.Exists(fullPath))
            {
                CLog.E(_tag, $"WriteAllBytes...Delete.....{fullPath}");
                File.Delete(fullPath);
            }
            FileStream fs = new FileStream(fullPath, FileMode.OpenOrCreate, FileAccess.Write);
            for (int i = 0; i < byteArrArr.Length; i++)
            {
                var byteArr = byteArrArr[i];
                fs.Write(byteArr, 0, byteArr.Length);
            }
            fs.Close();
        }

        /// <summary>
        /// 获取目录下所有匹配的文件--支持二级搜索目录
        /// </summary> 
        public static List<string> GetFiles(string _dir, string[] midDirArr, string[] _ignoreDirArr, string[] suffixArr, bool isTop, int isGetFileSystemType, List<string> pathList = null)
        {
            if (pathList == null)
            {
                pathList = new List<string>();
            }
            if (isTop)
            {
                GetFiles(_dir, suffixArr, isTop, isGetFileSystemType, pathList);
            } else
            {
                //bool topDirIsMatching = _topDirIsMatching(_dir, midDirArr, _ignoreDirArr);
                string[] fileArr = Directory.GetDirectories(_dir, "*", SearchOption.AllDirectories);
                for (int i = 0, j = fileArr.Length; i < j; i++)
                {
                    var fullPath = fileArr[i];
                    var _fullPath = fullPath.Substring(_dir.Length);
                    bool isIgnore = CString.IsMatching(_fullPath, _ignoreDirArr, EMatchingType.Contains);
                    if (isIgnore)
                    {
                        continue;
                    }
                    if (midDirArr == null || midDirArr.Length == 0)
                    {
                        GetFiles(fullPath, suffixArr, isTop, isGetFileSystemType, pathList);
                    } else
                    {
                        bool isMatching = CString.IsMatching(_fullPath, midDirArr, EMatchingType.Contains);
                        if (isMatching)
                        {
                            GetFiles(fullPath, suffixArr, isTop, isGetFileSystemType, pathList);
                        }
                    }
                }
            }
            return pathList;
        }

        static bool _topDirIsMatching(string fullPath, string[] midDirArr, string[] _ignoreDirArr)
        {
            bool isIgnore = CString.IsMatching(fullPath, _ignoreDirArr, EMatchingType.Contains);
            if (isIgnore)
            {
                return false;
            }
            bool isMatching = false;
            if (midDirArr == null || midDirArr.Length == 0)
            {
                isMatching = true;
            } else
            {
                isMatching = CString.IsMatching(fullPath, midDirArr, EMatchingType.Contains);
            }
            return isMatching;
        }

        /// <summary>
        /// 获取目录下所有匹配的文件
        /// </summary> 
        public static List<string> GetFiles(string _dir, string[] suffixArr, bool isTop, byte isGetFileSystemType)
        {
            return GetFiles(_dir, suffixArr, isTop, isGetFileSystemType, null);
        }

        /// <summary>
        /// 获取目录下所有匹配的文件
        /// </summary> 
        public static List<string> GetFiles(string _dir, string[] suffixArr, bool isTop, int isGetFileSystemType, List<string> pathList)
        {
            if (pathList == null)
            {
                pathList = new List<string>();
            }
            string[] pathArr = null;
            if (isGetFileSystemType == 1)
            {
                pathArr = Directory.GetDirectories(_dir, "*", isTop ? SearchOption.TopDirectoryOnly : SearchOption.AllDirectories);
            } else if (isGetFileSystemType == 2)
            {
                pathArr = Directory.GetFiles(_dir, "*", isTop ? SearchOption.TopDirectoryOnly : SearchOption.AllDirectories);
            } else if (isGetFileSystemType == 3)
            {
                pathArr = Directory.GetFileSystemEntries(_dir, "*", isTop ? SearchOption.TopDirectoryOnly : SearchOption.AllDirectories);
            }
            for (int i = 0, j = pathArr.Length; i < j; i++)
            {
                var filePath = pathArr[i];
                if (suffixArr != null && suffixArr.Length > 0)
                {
                    if (CString.IsMatching(filePath, suffixArr, EMatchingType.EndsWith))
                    {
                        pathList.Add(filePath);
                    }
                } else
                {
                    pathList.Add(filePath);
                }
            }
            return pathList;
        }
        #if UseZipArchive
        public static void ZipFile(string sourcePath, string zipOutputPath) {
            #if UNITY_2021_1_OR_NEWER
            System.IO.Compression.ZipFile.CreateFromDirectory(sourcePath, zipOutputPath); //压缩文件
            #else
			ZipFile2(sourcePath, zipOutputPath);
            #endif
        }

        public static void ZipFile2(string sourcePath, string zipOutputPath, string[] ignoreSuffixArr = null) {
            CFile.CreatePathParentDir(zipOutputPath);
            sourcePath = new DirectoryInfo(sourcePath).FullName;
            sourcePath = sourcePath.Replace('\\', '/');

            // 创建并添加被压缩文件
            using(FileStream zipFileToOpen = new FileStream(zipOutputPath, FileMode.Create))
                using(ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Create)) {
                    if(Directory.Exists(sourcePath)) {
                        if(sourcePath.EndsWith("/", StringComparison.Ordinal)) {
                            sourcePath = sourcePath.Substring(0, sourcePath.Length - 1);
                        }
                        var filePathArr = Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories);
                        for(int i2 = 0; i2 < filePathArr.Length; i2++) {
                            string path = filePathArr[i2];
                            if(path.IsMatching(ignoreSuffixArr, EMatchingType.EndsWith)) {
                                continue;
                            }
                            string filename = path.Substring(sourcePath.Length + 1);
                            _AddFile(archive, path, filename);
                        }
                    } else if(File.Exists(sourcePath)) {
                        var filename = Path.GetFileName(sourcePath);
                        _AddFile(archive, sourcePath, filename);
                    }
                }

            void _AddFile(ZipArchive archive, string path, string filename) {
                try {
                    byte[] bytes = File.ReadAllBytes(path);
                    ZipArchiveEntry readMeEntry = archive.CreateEntry(filename);
                    using(Stream stream = readMeEntry.Open()) {
                        stream.Write(bytes, 0, bytes.Length);
                    }
                } catch(Exception ex) {
                    CLog.Ee(_tag, path, ex);
                }
            }
        }

        public static void UnZipFile(string zipFilePath, string unZipOutputPath) {
            // 读取其中一个文件的内容
            using(FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)) {
                using(ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)) {
                    var list = archive.Entries;
                    for(int i2 = 0; i2 < list.Count; i2++) {
                        ZipArchiveEntry entry = list[i2];
                        //ZipArchiveEntry entry = archive.GetEntry("ZipArchiveSample.exe"); 
                        CLog.i(_tag, $"解压文件.....{unZipOutputPath}....{entry.Name}...{entry.FullName}");
                        using(var stream = entry.Open()) {
                            var fullPath = $"{unZipOutputPath}/{entry.FullName}";
                            CFile.CreatePathParentDir(fullPath, null);
                            var output = new FileStream(fullPath, FileMode.Create);
                            int b = -1;
                            while((b = stream.ReadByte()) != -1) {
                                output.WriteByte((byte)b);
                            }
                            output.Close();
                        }
                    }
                }
            }
        }
        #endif
        public static string CreateDir(string dir)
        {
            CLog.i(_tag, $"CreateDir....{dir}");
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            } else
            {
                //CLog.LogError("S_创建目录__失败__" + path);
            }
            return dir;
        }

        public static string CreatePathParentDir(string path, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"CreatePathParentDir....{callLog}......{path}");
            var dir = Path.GetDirectoryName(path);
            try
            {
                if (Directory.Exists(dir) == false)
                {
                    Directory.CreateDirectory(dir);
                } else
                {
                    //CLog.LogError("S_创建目录__失败__" + path);
                }
            } catch (Exception ex)
            {
                CLog.Ex(_tag, $"创建目录出错...{dir}", ex);
            }
            return dir;
        }

        public static bool DeleteDir(string dir, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"DeleteDir....{callLog}.....{dir}");
            try
            {
                if (Directory.Exists(dir))
                {
                    Directory.Delete(dir, true);
                }
                return true;
            } catch (Exception ex)
            {
                CLog.Ex(_tag, "删除目录出错:_" + dir, ex);
                return false;
            }
        }

        public static bool DeleteFile(string path, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"DeleteFile....{callLog}.....{path}");
            if (File.Exists(path) == false)
            {
                //CLog.E(tag, "无法删除不存在的文件.." + path);
                return true;
            }
            try
            {
                File.Delete(path);
                return true;
            } catch (Exception ex)
            {
                CLog.Ee(_tag, "删除文件出错:_" + path, ex);
                return false;
            }
        }

        public static void DeleteDirFile(string sourceDir, string searchPattern, SearchOption searchOption, string callLog = "")
        {
            sourceDir = new DirectoryInfo(sourceDir).FullName;
            if (Directory.Exists(sourceDir) == false)
            {
                CLog.E(_tag, $"无法拷贝.....目录不存在......{sourceDir}.....{searchPattern}");
                return;
            }
            if (callLog != null)
                CLog.i(_tag, $"删除目录文件..{callLog}......{sourceDir}.....{searchPattern}");
            var filePathArr = Directory.GetFiles(sourceDir, searchPattern, searchOption);
            for (int i = 0; i < filePathArr.Length; i++)
            {
                var filePath = filePathArr[i];
                File.Delete(filePath);
            }
        }

        public static void Delete(string path, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"Delete....{callLog}.....{path}");
            try
            {
                if (File.Exists(path))
                {
                    //CLog.E(tag, "无法删除不存在的文件.." + path);
                    File.Delete(path);
                } else if (Directory.Exists(path))
                {
                    Directory.Delete(path, true);
                }
            } catch (Exception ex)
            {
                CLog.Ee(_tag, "删除文件出错:_" + path, ex);
            }
        }

        public static string GetFileMd5(string fileName, string callLog = "")
        {
            if (callLog != null)
                CLog.i(_tag, $"GetFileMd5....{fileName}");
            try
            {
                FileStream file = new FileStream(fileName, FileMode.Open);
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] zData = md5.ComputeHash(file);
                md5.Clear();
                file.Close();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < zData.Length; i++)
                {
                    sb.Append(zData[i].ToString("x2"));
                }
                return sb.ToString();
            } catch (Exception ex)
            {
                CLog.Ee(_tag, "S_获取文件MD5值_出错:_", ex);
                return null;
            }
        }

        public static List<string> DfStrToFileList(string dfStr)
        {
            List<string> dirList = new List<string>();
            List<string> fileList = new List<string>();
            string[] dataArr = dfStr.Split('\n');

            int currIndex = 0;
            string currDirName = "";

            for (int i3 = 0; i3 < dataArr.Length; i3++)
            {
                string path = dataArr[i3];
                int index = path.IndexOf(CString.cSplit07);
                if (index >= 0)
                {
                    string[] sss = path.Split(CString.cSplit07);
                    currIndex = int.Parse(sss[0]);
                    currDirName = sss[1];
                    if (dirList.Count > currIndex)
                    {
                        dirList.Insert(currIndex, currDirName);
                    } else
                    {
                        dirList.Insert(currIndex, currDirName);
                    }
                } else
                {
                    string dirPath = "";
                    for (int i4 = 0; i4 < currIndex + 1; i4++)
                    {
                        dirPath += dirList[i4] + "/";
                    }
                    dirPath += path;
                    fileList.Add(dirPath);
                }
            }
            return fileList;
        }

        //移除文件列表的头部
        public static void RemoveFileListHead(string dir, List<string> fileList)
        {
            dir = dir.Replace('\\', '/');
            if (!dir.EndsWith("/"))
            {
                dir += "/";
            }
            int len = dir.Length;
            for (int i = 0, count = fileList.Count; i < count; i++)
            {
                string filePath = fileList[i];
                string _filePath = filePath.Substring(len).Replace('\\', '/');
                fileList.Insert(i, _filePath);
            }
        }

        public static string FileListToDfStr(List<string> fileList)
        {
            DirFile lastDirFile = new DirFile("");
            for (int i3 = 0; i3 < fileList.Count; i3++)
            {
                string filePath = fileList[i3];
                string[] dirNameArr = filePath.Replace('\\', '/').Split('/');
                lastDirFile.AddSub(dirNameArr, 0);
            }
            StringBuilder ssb = new StringBuilder();
            lastDirFile.Writestring(-1, ssb);
            return ssb.ToString();
        }

        public static ESuffixType GetFileType(string path)
        {
            ESuffixType suffixType = ESuffixType.other;
            var suffix = Path.GetExtension(path).ToLower();
            switch (suffix)
            {
                case ".html":
                    suffixType = ESuffixType.html;
                    break;
                case ".js":
                    suffixType = ESuffixType.js;
                    break;
                case ".cs":
                    suffixType = ESuffixType.cs;
                    break;
                case ".mp4":
                case ".mov":
                    suffixType = ESuffixType.video;
                    break;
                case ".png":
                case ".jpg":
                case ".jpeg":
                case ".tif":
                    suffixType = ESuffixType.image;
                    break;
                default:
                    suffixType = ESuffixType.other;
                    break;
            }
            return suffixType;
        }

        public class DirFile
        {
            public DirFile parentDir;
            public string dirName;
            public Dictionary<string, DirFile> dirFileDic;

            public DirFile(string dirName)
            {
                this.dirName = dirName;
            }

            public void AddSub(string[] dirNameArr, int index)
            {
                if (index >= dirNameArr.Length)
                {
                    return;
                }
                if (dirFileDic == null)
                {
                    dirFileDic = new Dictionary<string, DirFile>();
                }
                string dirName = dirNameArr[index];
                ++index;
                DirFile subDirFile;
                if (dirFileDic.ContainsKey(dirName))
                {
                    subDirFile = dirFileDic[dirName];
                } else
                {
                    subDirFile = new DirFile(dirName);
                    subDirFile.parentDir = this;
                    dirFileDic[dirName] = subDirFile;
                }
                subDirFile.AddSub(dirNameArr, index);
            }

            public void Writestring(int dirLayer, StringBuilder ssb)
            {
                if (dirFileDic != null && dirFileDic.Count > 0)
                {
                    if (dirLayer < 0)
                    { //这是根的空目录
                        dirLayer = 0;
                    } else
                    {
                        ssb.Append(dirLayer + (CString.cSplit07 + dirName + "\n"));
                        dirLayer++;
                    }
                    foreach (var kv in dirFileDic)
                    {
                        kv.Value.Writestring(dirLayer, ssb);
                    }
                } else
                {
                    ssb.Append(dirName + "\n");
                }
            }
        }
    }

    public enum ESuffixType
    {
        html, js, cs, image, video,
        audio, txt, other,
    }
}
